import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * AtomicInteger它提供了一种线程安全的方式来操作整数。
 * 利用了底层的原子操作来保证在多线程环境中对整数的增减操作是安全的，
 * 而不需要使用同步块（synchronized）。
 * 方法：
 * get()：返回当前的值
 * addAndGet(int delta)：原子地将当前值增加 delta，并返回新值
 * 优点：
 * AtomicInteger的主要优点是它提供了一种无锁的线程安全操作，
 * 这在某些情况下可以提高性能，尤其是在竞争激烈的环境中。
 * 它避免了使用传统的同步机制，如synchronized 块或方法，
 * 这些同步机制可能会导致线程阻塞和上下文切换，从而影响性能。
 * 区别：
 * 如果你的操作是简单的数值增减，并且对性能有较高要求，尤其是在高并发场景下，AtomicInteger 可能是更好的选择。
 * 如果你需要执行复杂的操作，或者需要保证操作的顺序，或者需要线程间的条件等待，synchronized 可能更适合。
 */
public class Test {
    private static final int[] arr;
    private static final AtomicInteger evenSum = new AtomicInteger(0);
    private static final AtomicInteger oddSum = new AtomicInteger(0);
    //在类加载时就初始化arr
    static {
        arr = new int[10000000];
        Random r = new Random();
        for (int i = 0; i < 10000000; i++) {
            arr[i] = r.nextInt(100);
        }
    }
    private static final Object locker = new Object();
    public static void main(String[] args) throws InterruptedException {
        //计算奇数下标的和
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10000000; i++) {
                if (i % 2 == 1) {
                    synchronized (locker) {
                        oddSum.addAndGet(arr[i]);
                    }
                }
            }
        });
        //计算偶数下标的和
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10000000; i++) {
                if (i % 2 == 0) {
                    synchronized (locker) {
                        evenSum.addAndGet(arr[i]);
                    }
                }
            }
        });
        t1.start();
        t2.start();
        long startTime = System.currentTimeMillis();
        t1.join();
        t2.join();
        long endTime = System.currentTimeMillis();
        System.out.println("相加的结果为："+(oddSum.get()+evenSum.get()));
        System.out.println("程序的执行时间为："+(endTime-startTime)+"毫秒");
    }
}
